<?php

class ZfApplication
{
	/**
	 * The environment state of your current application
	 *
	 * @var string
	 */
	protected $_environment;

	/**
	 * Enable Debuging? true: on, false: off
	 * @var boolean
	 */
	protected $_debug;

	/**
	 * Sets the environment to load from configuration file
	 *
	 * @param string $environment - The environment to set
	 * @return void
	 */
	public function setEnvironment($environment)
	{
		$this->_environment = $environment;
	}

	/**
	 * Returns the environment which is currently set
	 *
	 * @return string
	 */
	public function getEnvironment()
	{
		return $this->_environment;
	}

	public function setDebug($debug = false)
	{
		$this->_debug = $debug;
	}

	public function getDebug()
	{
		return $this->_debug;
	}

	/**
	 * Convenience method to bootstrap the application
	 *
	 * @return mixed
	 */
	public function bootstrap()
	{
		if (!$this->_environment) {
			throw new Exception('Please set the environment using ::setEnvironment');
		}

		$frontController = $this->initialize();

		//$this->setupRoutes($frontController);
		/*
		try
		{
			$response = $this->dispatch($frontController);
		}
		catch (Exception $e)
		{
			header('Location: /');
			exit(0);
		}
		
		$this->render($response);
		*/
	}

	/**
	 * Initialization stage, loads configration files, sets up includes paths
	 * and instantiazed the frontController
	 *
	 * @return Zend_Controller_Front
	 */
	public function initialize()
	{
		// Set Debug
		if ( $this->getDebug() && $this->getEnvironment() != 'production' )
		{
			ini_set('display_startup_errors','1');
			ini_set('display_errors','1');
			error_reporting( E_ALL|E_STRICT );
		} else {
			error_reporting(0);
		}

		// Set default timezone
		date_default_timezone_set('Asia/Shanghai');
		
		// Set the include path
		set_include_path(
			APPLICATION_PATH . '/../library'
			. PATH_SEPARATOR
			. get_include_path()
			);

		// register Zend autoload
		require_once 'Zend/Loader/Autoloader.php';
		$autoloader = Zend_Loader_Autoloader::getInstance();
		$autoloader->registerNamespace(array('Naneau_', 'Peter_'));

		// config init.
		$this->initConfig();

		$config = Zend_Registry::get('config');

		$application = new Zend_Application($this->getEnvironment(), $config);

		/*
		 * Create an instance of the frontcontroller, and point it to our
		 * controller directory
		 */
		$frontController = Zend_Controller_Front::getInstance();
		$frontController->throwExceptions((bool) $config->mvc->exceptions);

		// Set base url
		//$frontController->setBaseUrl('/app1');

		// Register plugins
		// Verify Plugin
		$frontController->registerPlugin(new Peter_Plugin_Verify())
			->registerPlugin(new Peter_Plugin_Profiling());

		$application->bootstrap()->run();
		
		return $frontController;
	}

	public function initConfig()
	{
		/*
		 * Load the given stage from our configuration file,
		 * and store it into the registry for later usage.
		 */
		$frontendOptions = array(
			'master_file' => APPLICATION_PATH . '/config/application.ini',
			);
		$cache = Zend_Cache::factory('File', 'APC', $frontendOptions);
		$cache_key = 'config_' . $this->getEnvironment();

		if ( true || !$result = $cache->load($cache_key))
		{
			$result = new Zend_Config_Ini( APPLICATION_PATH . '/config/application.ini', $this->getEnvironment());
			$cache->save(serialize($result), $cache_key);
			Zend_Registry::set('config', $result);
		}
		else
		{
			Zend_Registry::set('config', unserialize($result));
		}
	}

	/**
	 * Sets up the custom routes
	 *
	 * @param  object Zend_Controller_Front $frontController - The frontcontroller
	 * @return object Zend_Controller_Router_Rewrite
	 */
	public function setupRoutes(Zend_Controller_Front $frontController)
	{
		// Retrieve the router from the frontcontroller
		$router = $frontController->getRouter();

		/*
		 * You can add routes here like so:
		 * $router->addRoute(
		 *    'home',
		 *    new Zend_Controller_Router_Route('home', array(
		 *        'controller' => 'index',
		 *        'action'     => 'index'
		 *    ))
		 * );
		 */
		$router->addConfig(Zend_Registry::get('config'), 'routes');

		return $router;
	}

	/**
	 * Dispatches the request
	 *
	 * @param  object Zend_Controller_Front $frontController - The frontcontroller
	 * @return object Zend_Controller_Response_Abstract
	 */
	public function dispatch(Zend_Controller_Front $frontController)
	{
		// Return the response
		$frontController->returnResponse(true);
		return $frontController->dispatch();
	}

	/**
	 * Renders the response
	 *
	 * @param  object Zend_Controller_Response_Abstract $response - The response object
	 * @return void
	 */
	public function render(Zend_Controller_Response_Abstract $response)
	{
		$response->sendHeaders();
		$response->outputBody();
	}
}
